package cn.xiuxius.askbox.service.impl;

import cn.xiuxius.askbox.common.constant.AnswerState;
import cn.xiuxius.askbox.common.exception.BaseException;
import cn.xiuxius.askbox.common.utils.MailUtil;
import cn.xiuxius.askbox.mapper.AnswerMapper;
import cn.xiuxius.askbox.mapper.AskMapper;
import cn.xiuxius.askbox.pojo.dto.add.AnswerAddDTO;
import cn.xiuxius.askbox.pojo.dto.query.AnswerQueryDTO;
import cn.xiuxius.askbox.pojo.dto.update.AnswerUpdateDTO;
import cn.xiuxius.askbox.pojo.dto.update.AskUpdateStateDTO;
import cn.xiuxius.askbox.pojo.entity.AnswerEntity;
import cn.xiuxius.askbox.pojo.entity.AskEntity;
import cn.xiuxius.askbox.pojo.result.PageResult;
import cn.xiuxius.askbox.pojo.vo.AnswerVO;
import cn.xiuxius.askbox.service.IAnswerService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xiaoxiu
 * @since 2024-07-20
 */
@Service
public class AnswerServiceImpl extends ServiceImpl<AnswerMapper, AnswerEntity> implements IAnswerService {

    @Autowired
    private AnswerMapper answerMapper;

    @Autowired
    private AskMapper askMapper;

    @Autowired
    private MailUtil mailUtil;

    @Autowired
    private HttpServletRequest request;

    @Override
    public PageResult getAnswersByPage(AnswerQueryDTO dto) {
        LambdaQueryWrapper<AnswerEntity> wrapper = Wrappers.<AnswerEntity>lambdaQuery()
                .like(StringUtils.isNotBlank(dto.getAskUuid()),AnswerEntity::getAskUuid, dto.getAskUuid())
                .eq(Objects.nonNull(dto.getState()),AnswerEntity::getState, dto.getState())
                .like(StringUtils.isNotBlank(dto.getUserUuid()),AnswerEntity::getUserUuid, dto.getUserUuid())
                .like(StringUtils.isNotBlank(dto.getUuid()),AnswerEntity::getUuid, dto.getUuid())
                .like(StringUtils.isNotBlank(dto.getAgent()),AnswerEntity::getAgent, dto.getAgent())
                .like(StringUtils.isNotBlank(dto.getIp()),AnswerEntity::getIp, dto.getIp())
                .like(StringUtils.isNotBlank(dto.getContent()),AnswerEntity::getContent, dto.getContent())
                .between((dto.getCreateTimeBegin() != null && dto.getCreateTimeEnd() != null),AnswerEntity::getCreateTime, dto.getCreateTimeBegin(), dto.getCreateTimeEnd())
                .orderByDesc(AnswerEntity::getCreateTime);
        Page<AnswerEntity> pageResult = answerMapper.selectPage(new Page<>(dto.getPage(), dto.getPageSize()), wrapper);

        List<AnswerVO> vos = new LinkedList<>();

        for (AnswerEntity record : pageResult.getRecords()) {
            AnswerVO vo = new AnswerVO();
            BeanUtils.copyProperties(record, vo);
            vos.add(vo);
        }

        return new PageResult(pageResult.getTotal(), vos);
    }

    @Override
    public AnswerVO getAnswerByAnswerUuid(AnswerQueryDTO dto) {

        AnswerEntity answerEntity = answerMapper.selectOne(Wrappers.<AnswerEntity>lambdaQuery()
                .eq(AnswerEntity::getUuid, dto.getUuid())
                .eq(AnswerEntity::getState, dto.getState())
        );

        AnswerVO vo = new AnswerVO();

        BeanUtils.copyProperties(answerEntity, vo);

        return vo;
    }

    @Override
    public void updateAnswerByAnswerUuid(AnswerUpdateDTO dto) {
        answerMapper.update(null, Wrappers.<AnswerEntity>lambdaUpdate()
                .eq(AnswerEntity::getUuid, dto.getUuid())
                .set(StringUtils.isNotBlank(dto.getContent()),AnswerEntity::getContent, dto.getContent())
        );
    }

    @Override
    public void updateStateAnswerByAskUuid(AskUpdateStateDTO dto) {
        answerMapper.update(null, Wrappers.<AnswerEntity>lambdaUpdate()
                .eq(AnswerEntity::getUuid, dto.getUuid())
                .set(Objects.nonNull(dto.getState()),AnswerEntity::getState, dto.getState())
        );
    }

    @Override
    public void submitAnswer(AnswerAddDTO dto) {
        AskEntity askEntity = askMapper.selectOne(Wrappers.<AskEntity>lambdaQuery()
                .eq(AskEntity::getUuid, dto.getAskUuid())
        );
        if (askEntity.getAnswerState().equals(AnswerState.REPLIED)) {
            throw new BaseException("该问题已回复");
        }

        AnswerEntity answerEntity = new AnswerEntity();

        BeanUtils.copyProperties(dto, answerEntity);

        answerEntity.setIp(request.getRemoteAddr());
        answerEntity.setAgent(request.getHeader("User-Agent"));
        answerEntity.setUuid(UUID.randomUUID().toString());
        answerMapper.insert(answerEntity);

        //设置状态为已回复
        askEntity.setAnswerState(AnswerState.REPLIED);
        askMapper.update(Wrappers.<AskEntity>lambdaUpdate()
                .eq(AskEntity::getUuid, askEntity.getUuid())
                .set(AskEntity::getAnswerState, askEntity.getAnswerState())
        );

        //通知提问者

        StringBuilder content = new StringBuilder();

        content.append("<html>")
                .append("<body>")
                .append("<p>您的问题已被回复，请前往网站查看。</p>")
                .append("<p>问题内容：").append(askEntity.getContent()).append("</p>")
                .append("<p>回复内容：").append(answerEntity.getContent()).append("</p>")
                .append("<p>回复时间：").append(answerEntity.getCreateTime()).append("</p>")
                .append("</body>")
                .append("</html>");

        mailUtil.sendMail(askEntity.getReplyEmail(), "提问回复通知", content.toString());

    }

    @Override
    public AnswerVO getAnswerByAskUuid(AnswerQueryDTO dto) {
        AnswerEntity answerEntity = answerMapper.selectOne(Wrappers.<AnswerEntity>lambdaQuery()
                .eq(AnswerEntity::getAskUuid, dto.getAskUuid())
                .eq(Objects.nonNull(dto.getState()),AnswerEntity::getState, dto.getState())
        );

        AnswerVO vo = new AnswerVO();
        BeanUtils.copyProperties(answerEntity, vo);
        return vo;
    }
}
